package com.example.openim.websocket;

import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocket/user/{nanoID}/{phone}")
@Component
@Slf4j
public class WebSocketServer {

    private static MongoTemplate mongoTemplate;

    @Autowired
    public void setMongoTemplate(MongoTemplate mongoTemplate) {
        WebSocketServer.mongoTemplate = mongoTemplate;
    }

    /**
     * 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的
     */
    private static int onlineCount = 0;

    /**
     * concurrent 包的线程安全Set，用来存放每个客户端对应的 myWebSocket对象
     * 根据userId来获取对应的 WebSocket
     */
    private static Map<String, Map<String,Session>> roomUserSessions = new ConcurrentHashMap<>();


    private String ROOM_ID = "subSocket";


    /**
     * 连接建立成功调用的方法
     *
     * @param session
     * @param
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("nanoID") String nanoID, @PathParam("phone") String userId) {
        roomUserSessions.putIfAbsent(ROOM_ID, new ConcurrentHashMap<>());
        roomUserSessions.get(ROOM_ID).put(nanoID, session);
        log.info("webSocket建立连接---------》用户:{} 房间号:{}", nanoID, ROOM_ID);
    }

    /**
     * 关闭连接
     */

    @OnClose
    public void onClose(Session session, @PathParam("nanoID") String nanoID, @PathParam("phone") String userId) {
        Map<String, Session> userSessions = roomUserSessions.get(ROOM_ID);
        if (userSessions != null) {
            userSessions.remove(nanoID);
            log.info("webSocket关闭连接--------》移除 用户:{} 房间号:{}", nanoID, ROOM_ID);
            // 如果房间中没有用户了，移除房间
            if (userSessions.isEmpty()) {
                roomUserSessions.remove(ROOM_ID);
            }
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session,@PathParam("nanoID") String nanoID, @PathParam("phone") String userId) {
        // 处理来自客户端的消息逻辑
        log.info("webSocket收到来自客户端的消息 用户:{} 房间号:{} 消息:{}", nanoID, ROOM_ID, message);
        sendMessageToUserInRoom(userId, message, nanoID);
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        // 处理错误，例如记录日志
        log.info("WebSocket error: {}", throwable.getMessage());

    }

    /**
     * 保存或更新手机号数量记录
     * @param userId 手机号
     * @param message 数量
     */
    public void sendMessageToUserInRoom(String userId, String message, String nanoID) {
        log.info("webSocket向（{}）房间 -（{}）用户 - 发送消息（{}）", ROOM_ID, userId, message);
        Map<String, Session> userSessions = roomUserSessions.get(ROOM_ID);
        if (userSessions != null) {
            Session session = userSessions.get(nanoID);
            if (session != null && session.isOpen()) {
                session.getAsyncRemote().sendText("");

                // 处理数据库逻辑：解析消息并保存到SubSocket集合
                try {
                    upsertSubSocket(userId,Integer.parseInt(message));
                } catch (Exception e) {
                    log.error("处理数据库操作失败: ", e);
                }
            } else {
                log.info("webSocket通讯未连接---------》用户:{} 房间号:{} 消息:{}", nanoID, ROOM_ID, message);
            }
        } else {
            log.info("webSocket {} 房间不存在!!!", ROOM_ID);
        }
    }


    /**
     * Upsert SubSocket记录到数据库
     * @param phoneNumber 手机号
     * @param count 数量
     */
    private void upsertSubSocket(String phoneNumber, Integer count) {
        // 使用MongoDB的upsert操作
        // 查询条件
        Query query = new Query();
        query.addCriteria(Criteria.where("phone_number").is(phoneNumber));

        // 更新内容
        Update update = new Update();
        update.set("phone_number", phoneNumber);
        update.set("count", count);

        // 执行upsert操作
        mongoTemplate.upsert(query, update, "sub_socket");
        log.info("Upsert数据库记录: 手机号={}, 数量={}", phoneNumber, count);
    }

}
